#pragma once

#include "../Input/Keyboard.h"
#include "../Input/Mouse.h"
#include "../Utils/PlatTypeUtil.h"

class Input
{
private:
	Input();
	~Input() {}

	std::unique_ptr<Mouse> mMouse;
	Mouse::ButtonStateTracker mMouseTracker;
	std::unique_ptr<Keyboard> mKeyboard;
	Keyboard::KeyboardStateTracker mKeyboardTracker;

	Mouse::State mMouseState;
	Mouse::State mLastMouseState;
	Keyboard::State mKeyState;
	Keyboard::State mLastKeyState;

	float mMouseWheel;
	float mMouseWheelH;

	uint16 mInputChar;

public:

	static Input& Get();

	void SetWindow(HWND hwnd);

	void ProcessMouse(UINT message, WPARAM wParam, LPARAM lParam);

	void ProcessKeyboard(UINT message, WPARAM wParam, LPARAM lParam);

	void ProcessMouseWhell(UINT message, WPARAM wParam, LPARAM lParam);

	void ProcessMouseHWhell(UINT message, WPARAM wParam, LPARAM lParam);

	void ProcessInputChar(uint16 inputChar);

	void Update();

	bool IsKeyDown(Keyboard::Keys key) const;

	bool IsKeyUp(Keyboard::Keys key) const;

	bool IsLastKeyDown(Keyboard::Keys key) const;

	bool IsLastKeyUp(Keyboard::Keys key) const;

	bool LeftButton() const;

	bool MiddleButton() const;

	bool RightButton() const;

	bool XButton1() const;

	bool XButton2() const;

	int32 MouseX() const;

	int32 MouseY() const;

	int32 ScrollWheelValue() const;

	bool LastLeftButton() const;

	bool LastMiddleButton() const;

	bool LastRightButton() const;

	bool LastXButton1() const;

	bool LastXButton2() const;

	int32 LastMouseX() const;

	int32 LastMouseY() const;

	int32 LastScrollWheelValue() const;

	float MouseWheel();

	float MouseWheelH();

	uint16 InputChar();

};